import http from './http'

// ===== Notice APIs =====
// Page query: POST /intelligent-login/notice/page
export function pageNotices(data) {
  return http.post('/intelligent-login/notice/page', data)
}

// User-specific notices (includes readStatus/receiver info): GET /intelligent-login/notice/user
export function getUserNotices(params) {
  return http.get('/intelligent-login/notice/user', { params })
}

// Detail: prefer GET /intelligent-login/notice/detail/{id}
// Fallbacks: GET /intelligent-login/notice/detail?id=  ->  GET /intelligent-login/notice/{id}
export async function getNoticeDetail(id) {
  try {
    return await http.get(`/intelligent-login/notice/detail/${id}`)
  } catch (e) {
    try {
      return await http.get('/intelligent-login/notice/detail', { params: { id } })
    } catch (e2) {
      return await http.get(`/intelligent-login/notice/${id}`)
    }
  }
}

// Create: POST /intelligent-login/notice
export function createNotice(data) {
  return http.post('/intelligent-login/notice', data)
}

// Update: prefer PUT /intelligent-login/notice/update/{id}
// Fallback: PUT /intelligent-login/notice (body 含 id)
export async function updateNotice(id, data) {
  try {
    return await http.put(`/intelligent-login/notice/update/${id}`, data)
  } catch (e) {
    return http.put('/intelligent-login/notice', data)
  }
}

// Delete: prefer DELETE /intelligent-login/notice/delete/{id}
// Fallback: DELETE /intelligent-login/notice?id=
export async function deleteNotice(id) {
  try {
    return await http.delete(`/intelligent-login/notice/delete/${id}`)
  } catch (e) {
    return http.delete('/intelligent-login/notice', { params: { id } })
  }
}

// Stats: prefer GET /intelligent-login/notice/unread-count -> { unread }
// Fallback: GET /intelligent-login/notice/stats -> { unread, total? }
export async function getNoticeStats() {
  try {
    return await http.get('/intelligent-login/notice/unread-count')
  } catch (e) {
    return http.get('/intelligent-login/notice/stats')
  }
}

// Mark as read (single or multiple)
// Primary (new backend):
//  - Single: POST /intelligent-login/notice/mark-read/{id}
//  - Batch:  POST /intelligent-login/notice/batch/read  { ids: [] }
// Backward compatibility fallbacks (older backends):
//  - PUT  /intelligent-login/notice/read { ids: [] }
//  - GET  /intelligent-login/notice/read?ids=1&ids=2
//  - POST /intelligent-login/notice/markRead { ids: [] }
export async function markAsRead(ids) {
  const payload = Array.isArray(ids) ? ids : [ids]
  // Prefer new endpoints first
  try {
    if (payload.length === 1) {
      return await http.post(`/intelligent-login/notice/mark-read/${payload[0]}`)
    }
    return await http.post('/intelligent-login/notice/batch/read', { ids: payload })
  } catch (primaryErr) {
    // Fallback: try old endpoints in order
    try {
      return await http.put('/intelligent-login/notice/read', { ids: payload }, { showError: false })
    } catch (_) {
      try {
        return await http.get('/intelligent-login/notice/read', { params: { ids: payload } })
      } catch (__) {
        // last resort
        return await http.post('/intelligent-login/notice/markRead', { ids: payload }, { showError: false })
      }
    }
  }
}

// Optional: mark single
export function markOneAsRead(id) {
  // Call the unified method; it will route to the single-id endpoint
  return markAsRead(id)
}

// WebSocket/SSE connector (best-effort):
// It will attempt to open WebSocket first, and fallback to SSE if WS fails.
export function connectNoticeStream(handlers = {}) {
  const { onOpen, onMessage, onError, onClose } = handlers
  let ws
  let es
  let closed = false

  const host = window.location.host
  const isHttps = window.location.protocol === 'https:'
  const wsScheme = isHttps ? 'wss' : 'ws'

  const wsCandidates = [
    `${wsScheme}://${host}/api/intelligent-login/ws/notice`,
    `${wsScheme}://${host}/api/ws/notice`,
    `${wsScheme}://${host}/api/notice/ws`,
    `${wsScheme}://${host}/api/websocket/notice`,
  ]

  function closeAll() {
    closed = true
    if (ws) try { ws.close() } catch {}
    if (es) try { es.close() } catch {}
    ws = null; es = null
    onClose && onClose()
  }

  // Try WebSocket first
  try {
    ws = new WebSocket(wsCandidates[0])
    ws.onopen = () => { onOpen && onOpen() }
    ws.onmessage = (evt) => {
      let data
      try { data = JSON.parse(evt.data) } catch { data = evt.data }
      onMessage && onMessage(data)
    }
    ws.onerror = (e) => { onError && onError(e) }
    ws.onclose = () => {
      if (closed) return
      // fallback to SSE
      trySSE()
    }
  } catch {
    trySSE()
  }

  function trySSE() {
    try {
      es = new EventSource('/api/intelligent-login/sse/notice')
      es.onopen = () => { onOpen && onOpen() }
      es.onmessage = (evt) => {
        let data
        try { data = JSON.parse(evt.data) } catch { data = evt.data }
        onMessage && onMessage(data)
      }
      es.onerror = (e) => { onError && onError(e); closeAll() }
    } catch (e) {
      onError && onError(e)
    }
  }

  return () => closeAll()
}